package com.ytjj.qmyx.admin.service.channelProductService.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ytjj.common.constants.RedisConstants;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.HttpClientUtil;
import com.ytjj.qmyx.admin.config.SupplyApiConfig;
import com.ytjj.qmyx.admin.dao.ProductCategoryDao;
import com.ytjj.qmyx.admin.service.channelProductService.ChannelProductService;
import com.ytjj.qmyx.mall.mapper.ProductCategoryMapper;
import com.ytjj.qmyx.mall.model.ProductCategory;
import com.ytjj.qmyx.mall.model.ProductCategoryExample;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 *
 * 
 * @description:
 */

@Component
public class AsyncServiceImpl {
    @Autowired
    ChannelProductService channelProductService;

    @Autowired
    SupplyApiConfig supplyApiConfig;

    @Autowired
    RedisService redisService;

    @Autowired
    private ProductCategoryMapper productCategoryMapper;


    @Resource
    private RedissonClient redissonClient;

    @Autowired
    private ProductCategoryDao productCategoryDao;

    @Async
    public void refreshRedisCategory(){
        String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/prodouctCategory/list",null, supplyApiConfig.getHeadsMap());
        JSONObject parseObject = JSON.parseObject(resultJson);
        if(parseObject == null || !"200".equals(parseObject.get("code").toString())){
            throw new ApiException("接口调用出错");
        }
        System.out.println("进来了");
        List<ProductCategory> productCategoryAllList = JSONArray.parseArray(parseObject.getString("data"), ProductCategory.class);
        redisService.set(RedisConstants.SUPPLY_CHAIN_PRODUCT_CATEGORY_LIST, JSONArray.toJSONString(productCategoryAllList));
        redisService.expire(RedisConstants.SUPPLY_CHAIN_PRODUCT_CATEGORY_LIST, 10*60);
    }

    /**
     * 人工同步后台分类
     * @param :
     * @returns: int
     * 
     */
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void manualSynchronizationCategory() {
        RLock lock = redissonClient.getLock("MANUAL_SYNCHRONIZATION_CATEGORY_KEY");
        boolean b = false;
        try {
            b = lock.tryLock(0, 3600, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            lock.unlock();
            throw new ApiException("操作失败" + e.getMessage());
        }
        if (!b) {
            throw new ApiException("正在同步中，请稍后再试");
        }
        try {
            //供应链的分类
            List<ProductCategory> allProductCategorys = channelProductService.getAllProductCategorys();
            List<Integer> allProductIds = allProductCategorys.stream().map(ProductCategory::getId).collect(Collectors.toList());
            //app渠道的分类
            List<ProductCategory> productCategories = productCategoryMapper.selectByExample(new ProductCategoryExample());
            List<Integer> localIds = productCategories.stream().map(ProductCategory::getId).collect(Collectors.toList());
            //新增的分类id
            List<Integer> addIds = new ArrayList<>();
            List<ProductCategory> addData = new ArrayList<>();
            //删除的分类id
            List<Integer> delIds = new ArrayList<>();
            List<ProductCategory> delData = new ArrayList<>();

            addIds = allProductIds.stream().filter(e -> !localIds.contains(e)).collect(Collectors.toList());
            delIds = localIds.stream().filter(e -> !allProductIds.contains(e)).collect(Collectors.toList());
            //1.更新
            for (ProductCategory productCategory : productCategories) {
                for (ProductCategory allProductCategory : allProductCategorys) {
                    if (productCategory.getId().equals(allProductCategory.getId())) {
                        //判断是否要更新
                        if (!productCategory.equals(allProductCategory)) {
                            productCategoryMapper.updateByPrimaryKeySelective(allProductCategory);
                        }
                    }
                }
            }
            //2.删除
            for (Integer delId : delIds) {
                productCategoryMapper.deleteByPrimaryKey(delId);
            }

            //3.新增
            for (Integer addId : addIds) {
                Optional<ProductCategory> first = allProductCategorys.stream().filter(e -> e.getId().equals(addId)).findFirst();
                if (first.isPresent()) {
                    ProductCategory productCategory = first.get();
                    productCategory.setCreateTime(new Date());
                    productCategory.setUpdateTime(new Date());
                    addData.add(productCategory);
                }
            }
            if(addData.size() > 0){
                productCategoryDao.insertBatch(addData);
            }
        } catch (Exception e) {
            throw new ApiException("操作失败" + e.getMessage());
        } finally {
            //释放锁
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}
